package com.netsdk.aop;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharsetUtil;
import com.netsdk.utils.DeviceUtils;
import com.netsdk.utils.ResultUtil;
import lombok.SneakyThrows;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 服务拦截切面类（处理登录退出逻辑）
 *
 * @author gxsjx
 * @version 1.0
 * @date 2023/4/19
 * Copyright © wlinker.cn
 */
@Component
@Aspect
public class ServiceAspect {

    @Pointcut("execution(* com.netsdk.controller.CardController.*(..)) ")
    public void myPointcut() {
    }

    /**
     * 调用service.impl包下的任意类的任意方法时均会调用此方法
     */
    @Around("myPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取方法参数值数组
        Object[] args = joinPoint.getArgs();
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        //动态修改其参数
        //注意，如果调用joinPoint.proceed()方法，则修改的参数值不会生效，必须调用joinPoint.proceed(Object[] args)
        try {
            assert sra != null;
            HttpServletRequest request = sra.getRequest();
            String deviceNo = request.getParameter("deviceNo");
            Assert.notBlank(deviceNo, "设备编号不能为空");
            //登录
            DeviceUtils.login(deviceNo);
            Object result = joinPoint.proceed(args);
            //如果这里不返回result，则目标对象实际返回值会被置为null
            return result;
        } catch (Exception exception) {
            exception.printStackTrace();
            return sendResponse(sra, exception.toString());
        }finally {
            //退出登录
            DeviceUtils.logout();
        }
    }

    @SneakyThrows
    Object sendResponse(ServletRequestAttributes sra, String msg) {
        return sendResponse(sra, -1, msg);
    }

    @SneakyThrows
    Object sendResponse(ServletRequestAttributes sra, int code, String msg) {
        HttpServletResponse response = sra.getResponse();
        assert response != null;
        response.setContentType("application/json");
        response.setCharacterEncoding(CharsetUtil.defaultCharsetName());
        return ResultUtil.error(code, msg);
    }
}